﻿using CMS6Tools.Common.Email;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.ProcessConfiguration.Client;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;

namespace CMS6Tools.TFSTasks.Tasks
{
    public class TfsSendBugReportTask : TfsTask
    {
        const string AssignToFieldReferenceName = "System.AssignedTo";
#if DEBUG
        static readonly string[] EmailMembers = new string[]{"yding@visioninternet.com"};
#else
        static readonly string[] EmailMembers = (ConfigurationManager.AppSettings["BugReportMailToMembers"] ?? "").Split(',').Where(a=>a.Length>0).ToArray();
#endif

        protected override void ExecuteInternal(params string[] args)
        {
            var selectedProjectName = SelectedProjectName;
            var teamService = tfsTeamProjectCollection.GetService<TfsTeamService>();
            var workItemStore = tfsTeamProjectCollection.GetService<WorkItemStore>();
            var configurationService = tfsTeamProjectCollection.GetService<TeamSettingsConfigurationService>();

            var projects = workItemStore.Projects.OfType<Project>();
            var cms6Project = projects.FirstOrDefault(a => a.Name.Equals(selectedProjectName));
            var selectedProjectUri = cms6Project.Uri;

            var team = teamService.GetDefaultTeam(selectedProjectUri.ToString(), new List<string>());
            var teamMembers = team.GetMembers(tfsTeamProjectCollection, Microsoft.TeamFoundation.Framework.Common.MembershipQuery.Expanded)
                                  .Where(a => a.IsActive && !a.IsContainer)
                                  .ToList();
            var memberList = new List<TeamMember>();
            foreach (var member in teamMembers)
            {
                var email = GetEmail(member.UniqueName);
                memberList.Add(new TeamMember
                {
                    Name = member.UniqueName,
                    Email = email,
                    DisplayName = member.DisplayName ?? member.UniqueName
                });
            }

            var queryBuilder = new StringBuilder();
            queryBuilder.Append("Select System.Id, System.Title from workitems where ");
            queryBuilder.AppendFormat(" [System.TeamProject] = '{0}' ", selectedProjectName);
            queryBuilder.Append(" AND [System.WorkItemType]='Bug' AND NOT(System.Title Contains 'Build Failure') ");
            queryBuilder.Append("AND [System.State] In ('Active','Resolved') ");
            //var iterationQueryBuilder = new StringBuilder(); 
            //queryBuilder.AppendFormat(" AND ({0})", iterationQueryBuilder.ToString());
            var workItemCollection = workItemStore.Query(queryBuilder.ToString());

            foreach (WorkItem item in workItemCollection)
            {
                var assignToField = (string)(item.Fields[AssignToFieldReferenceName].Value ?? string.Empty);
                if (!string.IsNullOrEmpty(assignToField))
                {
                    var teamMember = memberList.FirstOrDefault(a => a.DisplayName.Equals(assignToField));
                    if (teamMember != null)
                    {
                        teamMember.WorkItems.Add(item);
                    }
                }
            }
            //memberList = memberList.Where(a => a.DisplayName == "Yuliang Ding").ToList();

            var emailService = new EmailService(); 
            var emailTemplate = CreateEmailTemplate("BugReportEmailTemplate.xslt");

            var totalSummary = new Dictionary<string, Dictionary<string, string>>();
            foreach (var member in memberList.OrderBy(a => a.DisplayName).ToList())
            {
                var tDict = new Dictionary<string, string>();
                tDict["Name"] = member.DisplayName;
                tDict["Active"] = member.WorkItems.Count(a => a.State == "Active").ToString();
                tDict["Resolved"] = member.WorkItems.Count(a => a.State == "Resolved").ToString();
                totalSummary.Add(member.DisplayName, tDict);
            }
            var sumDict = new Dictionary<string, string>();
            sumDict["Name"] = "Total";
            sumDict["Active"] = memberList.Sum(a => a.WorkItems.Count(b => b.State == "Active")).ToString();
            sumDict["Resolved"] = memberList.Sum(a => a.WorkItems.Count(b => b.State == "Resolved")).ToString();
            totalSummary.Add("Total", sumDict);

            foreach (var member in memberList)
            {
                if (EmailMembers.Length == 0 || EmailMembers.Any(a => a.Equals(member.Email)))
                {
                    var emailTemplateExtraData = new TextTemplateExtraData();
                    emailTemplateExtraData.Add("DisplayName", member.DisplayName);
                    emailTemplateExtraData.Add("Count", member.WorkItems.Count.ToString());
                    emailTemplateExtraData.Add("TotalStart", (member.WorkItems.Count + 1).ToString());                
                    emailTemplateExtraData.Add("TotalCount", (member.WorkItems.Count + memberList.Count + 1).ToString());
                    emailTemplateExtraData.Add("MyBugsURL", "http://10.10.2.41:8090/tfs/CMSCollection/CMS%206/_workitems#path=Shared+Queries%2FMy+Active+%26+Resolved+Bugs&_a=query");

                    int i = 1;
                    foreach (var workItem in member.WorkItems.OrderBy(a => a.State).OrderByDescending(a => a.Id))
                    {
                        try
                        {
                            var temDic = new Dictionary<string, string>();
                            temDic.Add("ID", workItem.Id.ToString());
                            temDic.Add("Href", string.Format("http://10.10.2.41:8090/tfs/CMSCollection/CMS%206/_workitems#id={0}&triage=true&_a=edit", workItem.Id));
                            temDic.Add("Title", workItem.Title);
                            temDic.Add("State", workItem.State);
                            temDic.Add("Reason", workItem.Reason);
                            temDic.Add("ChangedDate", workItem.ChangedDate.ToString());
                            temDic.Add("ChangedBy", workItem.ChangedBy);

                            emailTemplateExtraData.AddDictionary(i, temDic);
                            i++;
                        }
                        catch (Exception ex)
                        {
                        }
                    }

                    foreach (var key in totalSummary.Keys)
                    {
                        emailTemplateExtraData.AddDictionary(i++, totalSummary[key]);
                    }

                    var to = new MailAddress[] { new MailAddress(member.Email, member.DisplayName) };
                    emailService.SendEmail(to, emailTemplate, aSyncSend: false, extraData: emailTemplateExtraData);
                }
            }
        }
    }

    public class TeamMember 
    {
        public TeamMember()
        {
            WorkItems = new List<WorkItem>();
        }

        public string Name { get; set; }
        public string DisplayName { get; set; }
        public string Email { get; set; }
        public List<WorkItem> WorkItems { get; set; }
    }
}
